// 1. Ending a finally block with return
function foo() {
  try {
    throw new Error('error!');
  } catch(err) {
    return err.message;
  } finally {
    // this supersedes any previous return in try-catch block
    return 'From finally block';
  }
}

// The incorrect value is returned.
console.log(foo()); // Outputs 'From finally block'

// 2. Ending a finally block with break
function neverPlusOne() {
    for (;;) {
        try {
            return 1;
        } finally {
            break;
        }
    }
    return -1
}

// Always returns -1 because break in finally block overrides early return 1.
console.log(neverPlusOne());

// 3. Ending a finally block with continue
function foo2() {
    try {
        throw new Error('Error');
    } catch(err) {
        return err.message;
    } finally {
        continue; // Error thrown 
    }
}

// 4. Ending a finally block by throwing an exception
function foo3() {
    try {
        throw new Error('Error1');
    } finally {
        throw new Error('Error2');
    }
}

// Error2 is the exception shown, it supersedes Error1.
console.log(foo3());
